package com.twitter.home_mixer.product.scored_tweets

import com.twitter.home_mixer.model.HomeFeatures.ServedTweetIdsFeature
import com.twitter.home_mixer.model.HomeFeatures.TimelineServiceTweetsFeature
import com.twitter.home_mixer.model.request.HomeMixerRequest
import com.twitter.home_mixer.model.request.ScoredTweetsProduct
import com.twitter.home_mixer.model.request.ScoredTweetsProductContext
import com.twitter.home_mixer.product.scored_tweets.model.ScoredTweetsQuery
import com.twitter.home_mixer.product.scored_tweets.param.ScoredTweetsParam.ServerMaxResultsParam
import com.twitter.home_mixer.product.scored_tweets.param.ScoredTweetsParamConfig
import com.twitter.home_mixer.service.HomeMixerAccessPolicy.DefaultHomeMixerAccessPolicy
import com.twitter.home_mixer.{thriftscala => t}
import com.twitter.product_mixer.component_library.premarshaller.cursor.UrtCursorSerializer
import com.twitter.product_mixer.core.feature.featuremap.FeatureMapBuilder
import com.twitter.product_mixer.core.functional_component.common.access_policy.AccessPolicy
import com.twitter.product_mixer.core.model.common.identifier.ComponentIdentifier
import com.twitter.product_mixer.core.model.common.identifier.ProductPipelineIdentifier
import com.twitter.product_mixer.core.model.marshalling.request.Product
import com.twitter.product_mixer.core.pipeline.PipelineConfig
import com.twitter.product_mixer.core.pipeline.pipeline_failure.BadRequest
import com.twitter.product_mixer.core.pipeline.pipeline_failure.PipelineFailure
import com.twitter.product_mixer.core.pipeline.product.ProductPipelineConfig
import com.twitter.product_mixer.core.product.ProductParamConfig
import com.twitter.timelines.configapi.Params
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class ScoredTweetsProductPipelineConfig @Inject() (
  //这是一个构造函数，使用依赖注入（@Inject）来初始化管道配置。
  // 它接收 scoredTweetsRecommendationPipelineConfig（推荐管道配置）和 scoredTweetsParamConfig（参数配置）。
  scoredTweetsRecommendationPipelineConfig: ScoredTweetsRecommendationPipelineConfig,
  scoredTweetsParamConfig: ScoredTweetsParamConfig)
    extends ProductPipelineConfig[HomeMixerRequest, ScoredTweetsQuery, t.ScoredTweets] {
  //这行代码定义了产品管道的唯一标识符，用于在系统中标识和引用这个特定的产品管道。
  override val identifier: ProductPipelineIdentifier = ProductPipelineIdentifier("ScoredTweets")
  //指定这个管道配置所处理的产品类型，即 ScoredTweetsProduct。
  override val product: Product = ScoredTweetsProduct

  override val paramConfig: ProductParamConfig = scoredTweetsParamConfig
  //这个方法负责将 HomeMixerRequest 请求转换为 ScoredTweetsQuery 查询。
  // 它首先检查请求中是否包含合适的产品上下文，然后构建特征映射，并创建查询对象。
  override def pipelineQueryTransformer(
    request: HomeMixerRequest,
    params: Params
  ): ScoredTweetsQuery = {
    val context = request.productContext match {
      case Some(context: ScoredTweetsProductContext) => context
      case _ => throw PipelineFailure(BadRequest, "ScoredTweetsProductContext not found")
    }

    val featureMap = FeatureMapBuilder()
      .add(ServedTweetIdsFeature, context.servedTweetIds.getOrElse(Seq.empty))
      .add(TimelineServiceTweetsFeature, context.backfillTweetIds.getOrElse(Seq.empty))
      .build()

    ScoredTweetsQuery(
      params = params,
      clientContext = request.clientContext,
      pipelineCursor =
        request.serializedRequestCursor.flatMap(UrtCursorSerializer.deserializeOrderedCursor),
      requestedMaxResults = Some(params(ServerMaxResultsParam)),
      debugOptions = request.debugParams.flatMap(_.debugOptions),
      features = Some(featureMap),
      deviceContext = context.deviceContext,
      seenTweetIds = context.seenTweetIds,
      qualityFactorStatus = None
    )
  }
  //定义了此产品管道将执行的实际管道配置列表。在这种情况下，它使用了 scoredTweetsRecommendationPipelineConfig。
  override val pipelines: Seq[PipelineConfig] = Seq(scoredTweetsRecommendationPipelineConfig)
  //为给定的查询选择适当的管道来执行。这里，它始终选择 scoredTweetsRecommendationPipelineConfig。
  override def pipelineSelector(query: ScoredTweetsQuery): ComponentIdentifier =
    scoredTweetsRecommendationPipelineConfig.identifier

  override val debugAccessPolicies: Set[AccessPolicy] = DefaultHomeMixerAccessPolicy
}
